using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.Domain.Repositories;
using Abp.Extensions;
using Abp.Linq.Extensions;
using Abp.Timing;
using Abp.UI;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using SOEI.Solution.Application.Contracts.Customized.Organization;
using SOEI.Solution.Customized;
using SOEI.Solution.Customized.Dtos;
using SOEI.Solution.DomainEntities.Parameters.DomainService;
using SOEI.Solution.Helper;
using SOEI.Solution.Integratedes.ElectronicSignet;
using SOEI.Solution.Integratedes.ElectronicSignet.DomainService;
using SOEI.Solution.Integratedes.ElectronicSignet.Dtos;
using SOEI.Solution.Integratedes.Organization.DomainService;
using SOEI.Solution.Integratedes.Organization.Dtos;
using SOEI.Solution.ThirdParty.ESignClient.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using ThirdParty.ESignClient;

namespace SOEI.Solution.Integratedes.Organization
{
    /// <summary>
    /// 【扩展模块】  <br/>
    /// 【功能描述】  ：我的机构信息 模块<br/>
    /// 【创建日期】  ：2020.05.21 <br/>
    /// 【开发人员】  ：static残影<br/>
    ///</summary>
    [AbpAuthorize]
    [ApiExplorerSettings(GroupName = "Manager", IgnoreApi = false)]
    public class OursEconomyOrganiAppService : SolutionAppServiceBase, IOursEconomyOrganiAppService
    {
        /// <summary>
        ///【OEconomyOrgani】仓储层
        /// </summary>
        private readonly IRepository<OEconomyOrgani, string> _oeconomyorganiRepository;

        /// <summary>
        /// 【Parameter】参数的领域服务
        /// </summary>
        private readonly IParameterManager _parameterManager;

        /// <summary>
        /// 【OEconomyOrgani】机构人员领域服务
        /// </summary>
        private readonly IOEconomyPersonManager _oEconomyPersonManager;

        /// <summary>
        ///【机构领域】 机构领域服务
        /// </summary>
        private readonly IOEconomyOrganiManager _oeconomyorganiManager;

        /// <summary>
        /// 【电子签章】电子签章领域服务
        /// </summary>
        private readonly IOrgSignetManager _orgSignetManager;

        /// <summary>
        /// 【E签宝】 领域服务
        /// </summary>
        private readonly IESignManager _eSignManager;

        /// <summary>
        /// 【承若书】承若书领域服务
        /// </summary>
        private readonly IPledgeBookManager _pledgeBookManager;

        public OursEconomyOrganiAppService(
            IRepository<OEconomyOrgani, string> oeconomyorganiRepository,
            IOEconomyOrganiManager oeconomyorganiManager,
            IOEconomyPersonManager oEconomyPersonManager,
            IParameterManager parameterManager,
            IOrgSignetManager orgSignetManager,
            IPledgeBookManager pledgeBookManager,
        IESignManager eSignManager
        )
        {
            _oeconomyorganiRepository = oeconomyorganiRepository;
            _oeconomyorganiManager = oeconomyorganiManager;
            _oEconomyPersonManager = oEconomyPersonManager;
            _parameterManager = parameterManager;
            _orgSignetManager = orgSignetManager;
            _pledgeBookManager = pledgeBookManager;
            _eSignManager = eSignManager;
        }

        #region -------------------------------------------------辅助工具生成---------------------------------------------- 

        #endregion

        #region -------------------------------------------------用户自定义------------------------------------------------
        /*请在此扩展应用服务实现*/

        /// <summary>
        /// 获取我的机构信息（必须有当前登录的用户，如果是Admin登录没有机构信息则返回一个空的机构）【机构信息】
        /// </summary>
        /// <param></param>
        /// <returns></returns>
        public async Task<OEconomyOrganiListDto> GetOwenOrgani()
        {
            // 1. 获取当前登录的用户信息（）
            var userEntity = await this.GetPersonChecker();

            //2. 判断当前登录 是否经济机构用户

            var orgniEntity = await this._oeconomyorganiManager.GetEntityByIdAsync(userEntity.OriginalNumber);

            if (orgniEntity == null)
            {
                orgniEntity = new OEconomyOrgani();
                orgniEntity.JGZT = ((int)EApprovalStatus.WaitSubmit).ToString();
                orgniEntity.JGZTMC = "待提交";
                orgniEntity.IdentifyModuleID = Guid.NewGuid();
                orgniEntity.LicenseModuleID = Guid.NewGuid();
            }

            orgniEntity.IdentifyModuleID = orgniEntity.IdentifyModuleID == Guid.Empty ? Guid.NewGuid() : orgniEntity.IdentifyModuleID;
            orgniEntity.LicenseModuleID = orgniEntity.LicenseModuleID == Guid.Empty ? Guid.NewGuid() : orgniEntity.LicenseModuleID;

            // 我的机构初始化默认字段
            orgniEntity.KZJQDMMHTBH = "02"; // 买卖合同签订编号
            orgniEntity.JJHTJYBH = "02"; // 经纪合同效验编号
            orgniEntity.JYGPXXBH = "02"; // 校验挂牌信息编号
            orgniEntity.KWQ = "0"; // 可网签
            orgniEntity.SFGTGSH = string.Empty; // 是否个体工商户
            orgniEntity.SFYQ = string.Empty; // 是否网签
            
            // 默认字段以后需要补全
            var dto = ObjectMapper.Map<OEconomyOrganiListDto>(orgniEntity);
            // 是否允许电子签章（同时必须完成了备案初始化）
            dto.UseSignet &= await this._orgSignetManager.UseSignet(orgniEntity.Id);
            // 是否允许电子印章授权（同时必须完成了初始化备案表，和电子印章申请才可以授权）
            dto.UseGrant &= !dto.UseSignet;
            // 是否允许新模式服务许可
            dto.UseLicense = dto.UseGrant;

            
            return dto;
        }

        /// <summary>
        /// 获取我的备案信息【机构信息】
        /// </summary>
        /// <param></param>
        /// <returns></returns>
        public async Task<OEconomyOrganiListDto> GetOwenOrganiRecord()
        {
            // 1. 获取当前登录的用户信息（）
            var userEntity = await this.GetPersonChecker();
            // 2. 获取Zhxt机构信息
            var orgniEntity = await this._oeconomyorganiManager.GetEntityByIdAsync(userEntity.OriginalNumber);

            if (orgniEntity == null)
            {
                orgniEntity = new OEconomyOrgani();
                orgniEntity.JGZT = ((int)EApprovalStatus.WaitSubmit).ToString();
                orgniEntity.JGZTMC = "待提交";
            }
            //orgniEntity.IdentifyModuleID = orgniEntity.IdentifyModuleID == Guid.Empty ? Guid.NewGuid() : orgniEntity.IdentifyModuleID;
            //orgniEntity.LicenseModuleID = orgniEntity.LicenseModuleID == Guid.Empty ? Guid.NewGuid() : orgniEntity.LicenseModuleID;
            // 我的机构初始化默认字段
            orgniEntity.KZJQDMMHTBH = "02"; // 买卖合同签订编号
            orgniEntity.JJHTJYBH = "02"; // 经纪合同效验编号
            orgniEntity.JYGPXXBH = "02"; // 校验挂牌信息编号
            orgniEntity.KWQ = "0"; // 可网签
            orgniEntity.SFGTGSH = string.Empty; // 是否个体工商户
            orgniEntity.SFYQ = string.Empty; // 是否网签
                                             // 默认字段以后需要补全
            var dto = ObjectMapper.Map<OEconomyOrganiListDto>(orgniEntity);
            // 是否允许电子签章（同时必须完成了备案初始化）
            dto.UseSignet &= await this._orgSignetManager.UseSignet(orgniEntity.Id);
            // 是否允许电子印章授权（同时必须完成了初始化备案表，和电子印章申请才可以授权）
            dto.UseGrant &= !dto.UseSignet;
            // 是否允许新模式服务许可
            dto.UseLicense = dto.UseGrant;
            return dto;
        }

        /// <summary>
        /// 提交备案数据(临时保存)【机构信息】
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        // [AbpAuthorize(EconomyOrganiPermissions.Node)]
        public async Task OwenUpdate(OEconomyOrganiEditDto input)
        {
            var userEntity = await this.GetPersonChecker();

            if (!string.IsNullOrEmpty(input.Id))
            {
                //TODO:更新前的逻辑判断，是否允许更新
                var entity = await _oeconomyorganiManager.GetEntityByIdAsync(input.Id);
                //将input属性的值赋值到entity中
                ObjectMapper.Map(input, entity);
                await _oeconomyorganiManager.UpdateAsync(entity);
            }
            else
            {
                await this.CreateOrganization(userEntity.OriginalNumber);
            }

        }

        /*请在此扩展应用服务实现*/

        /// <summary>
        /// 提交初始化备案【机构信息】
        /// </summary>
        public async Task SubmitInitRecord()
        {
            // 1. 获取当前登录的用户信息（）
            var userEntity = await this.GetPersonChecker();
            // 2. 机构信息提交
            await _oeconomyorganiManager.SubmitInitRecord(userEntity.OriginalNumber);
            // 3. 机构人员信息提交
            await _oEconomyPersonManager.SubmitInitRecord(userEntity.OriginalNumber);
            // 4. 为经济机构生成系统账号()


        }

        #endregion

        #region -------------------------------------------------电子印章------------------------------------------------

        /// <summary>
        /// 1.获取机构电子印章申请【电子印章】
        /// </summary>
        /// <returns></returns>
        public async Task<OrgSignetOutput> GetOwenOrganiSignet()
        {
            var output = new OrgSignetOutput();
            // 1. 获取当前登录的用户信息
            var userEntity = await this.GetPersonChecker();
            if (userEntity.UserType != EUserType.Administrator)
            {
                throw new UserFriendlyException("当前登录用户不是机构管理员无法继续操作！");
            }
            // 2. 获取当前登录用户的所属机构信息（一定是备案过的）
            var orgniEntity = await this._oeconomyorganiManager.GetEntityByIdAsync(userEntity.OriginalNumber);
            // 3. 获取电子印章数据(不存在则创建一个新的)
            var orgSignetEntity = await this._orgSignetManager.GetCreateOrgSignetAsync(orgniEntity);
            // 4. 获取管理人员信息
            // var personEntity = await this._oEconomyPersonManager.GetAdminPersonEntityAsync(userEntity.NormalizedUserName);
            // 5. 获取E签宝的个人账号信息（不存在则创建一个新的）
            var personAccount = await GetAccountModel(orgSignetEntity, orgniEntity.ToAccountEntity());

            // 6. 获取E签宝的机构账号信息（不存在则创建一个新的）
            var orgniAccount = await GetOrgAccountModel(orgSignetEntity, orgniEntity.ToOrgniAccountEntity(orgSignetEntity));

            // 7. 设置个人账号
            orgSignetEntity.AccountID = personAccount.AccountID;
            orgSignetEntity.ORGID = orgniAccount.OrgId;
            // orgSignetEntity.ORGID = account.

            await this._orgSignetManager.UpdateAsync(orgSignetEntity);

            // 8. 发起个人刷脸实名认证
            //var faceResult = await this._eSignManager.FaceAsync(orgSignetEntity.AccountID, "TENCENT");
            //var invitation = await this._eSignManager.InvitationsAsync(orgSignetEntity.AccountID);

            output.OrgSignet = ObjectMapper.Map<OrgSignetEditDto>(orgSignetEntity);
            output.Account = personAccount;
            output.OrgAccount = orgniAccount;
            output.Organi = ObjectMapper.Map<OrganiViewDto>(orgniEntity);
            // 判断是否可以上传图片（如果机构表存在附件信息 则这里不允许在上传了， 仅包含身份证和营业执照）
            output.OrgSignet.IsExistIdentify = IsExistGuid(output.Organi.IdentifyModuleID);
            output.OrgSignet.IsExistLicense = IsExistGuid(output.Organi.LicenseModuleID);


            //output.Face = faceResult.Data;
            //output.Invitations = invitation.Data;
            return output;
        }



        /// <summary>
        /// 提交电子印章申请【电子印章】
        /// </summary>
        /// <param name="input">必须包含印章编号</param>
        /// <returns></returns>
        public async Task SubmitSignetRecord(OrgSignetInput input)
        {
            //1. 修改电子印章的状态为已提交
            var orgSignetEntity = await this._orgSignetManager.FindByIdAsync(input.Id);
            //2. 设置为待审核
            orgSignetEntity.Status = ((int)EApprovalStatus.WaitReview).ToString();
            //3. 更新电子印章实体
            await this._orgSignetManager.UpdateAsync(orgSignetEntity);
        }

        #endregion

        #region -------------------------------------------------我的新模式服务许可申请------------------------------------------------


        /// <summary>
        /// 获取我的机构初始化承诺书【新模式上门服务许可】
        /// </summary>
        /// <returns></returns>
        public async Task<OrgPledgeBookOutput> GetOwenOrganiPledgeBook()
        {
            var output = new OrgPledgeBookOutput();
            // 1. 获取当前登录的用户信息
            var userEntity = await this.GetPersonChecker();
            if (userEntity.UserType != EUserType.Administrator)
            {
                throw new UserFriendlyException("当前登录用户不是机构管理员无法继续操作！");
            }
            // 2. 获取当前登录用户的所属机构信息（一定是备案过的）
            var orgniEntity = await this._oeconomyorganiManager.GetEntityByIdAsync(userEntity.OriginalNumber);
            // 3. 获取当前机构的服务许可
            var PledgeBookEntity = await this._pledgeBookManager.GetCreatePledgeBookAsync(orgniEntity);
            // 4. 获取电子印章数据(不存在则创建一个新的)
            var orgSignetEntity = await this._orgSignetManager.GetCreateOrgSignetAsync(orgniEntity);
            // 5. 机构电子签章账号
            var account = await GetAccountModel(orgSignetEntity, orgniEntity.ToAccountEntity());
            
            output.Account = account;
            output.Organi  = ObjectMapper.Map<OrganiViewDto>(orgniEntity);
            output.PledgeBook = ObjectMapper.Map<PledgeBookEditDto>(PledgeBookEntity);
            return output;
        }

        /// <summary>
        /// 提交新模式许可申请【新模式上门服务许可】
        /// </summary>
        /// <param name="input">必须包含印章编号</param>
        /// <returns></returns>
        public async Task SubmitPledgeBook(EntityDto<long> input)
        {
            // 1. 获取当前登录的用户信息
            var userEntity = await this.GetPersonChecker();

            //1. 修改为已提交承若书
            var orgSignetEntity = await this._pledgeBookManager.FindByIdAsync(input.Id);
            //2. 设置为待审核
            orgSignetEntity.Status = ((int)EApprovalStatus.WaitReview).ToString();

            await this._pledgeBookManager.UpdateAsync(orgSignetEntity);
        }

        #endregion



        #region -------------------------------------------------机构注销相关------------------------------------------------

        /// <summary>
        /// 获取我的机构注销前信息
        /// </summary>
        /// <returns></returns>
        public async Task<OrganiCancelOutput> GetOwenOrganiForCancellation()
        {
            // 1. 获取当前登录的用户信息
            var userEntity = await this.GetPersonChecker();
            if (userEntity.UserType != EUserType.Administrator)
            {
                throw new UserFriendlyException("当前登录用户不是机构管理员无法继续操作！");
            }

            var output = new OrganiCancelOutput();
            // 2. 获取当前登录用户的所属机构信息（一定是备案过的）
            var orgniEntity = await this._oeconomyorganiManager.GetEntityByIdAsync(userEntity.OriginalNumber);
            // 3. 获取电子印章数据(不存在则创建一个新的)
            var orgSignetEntity = await this._orgSignetManager.GetCreateOrgSignetAsync(orgniEntity);
            // 4. 获取管理人员信息
            // var personEntity = await this._oEconomyPersonManager.GetAdminPersonEntityAsync(userEntity.NormalizedUserName);
            // 5. 获取E签宝的个人账号信息（不存在则为空）
            var personAccount = await GetAccountModel(orgSignetEntity, orgniEntity.ToAccountEntity(), false);
            // 6. 获取E签宝的机构账号信息（不存在则创建一个新的）
            var orgniAccount = await GetOrgAccountModel(orgSignetEntity, orgniEntity.ToOrgniAccountEntity(orgSignetEntity), false);
            // 7. 设置个人账号
            orgSignetEntity.AccountID = personAccount?.AccountID;
            orgSignetEntity.ORGID = orgniAccount?.OrgId;

            output.OrgSignet = ObjectMapper.Map<OrgSignetEditDto>(orgSignetEntity);
            output.Account = personAccount;
            output.OrgAccount = orgniAccount;
            output.Organi = ObjectMapper.Map<OrganiViewDto>(orgniEntity);
            output.OrganiCancel = new OEconomyOrganiCancelEditDto
            {
                JJJGBH = orgniEntity.Id,
                ZXRBH = userEntity.NormalizedUserName,
                ZXRMC = userEntity.Name
            };

            return output;
        }

        /// <summary>
        /// 提交注销申请
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task SubmitCancellation(OEconomyOrganiCancelEditDto input)
        {
            // 1. 获取当前登录的用户信息（）
            var userEntity = await this.GetPersonChecker();

            var entity = ObjectMapper.Map<OEconomyOrganiCancel>(input);
            // 提交撤销
            await this._oeconomyorganiManager.Cancellation(entity);
            // 当前经济机构的状态应该修改为注销中，目前还不确定 如有需要添加修改代码
        }

        #endregion

        #region  ----------------------------辅助方法-------------------------------

        /// <summary>
        /// 获取机构负责人电子签章个人账号
        /// </summary>
        /// <param name="orgSignet">电子签章实体</param>
        /// <param name="Account">个人账号</param>
        /// <param name="IsCreated">不存是是否创建新的默认创建新的</param>
        /// <returns></returns>
        protected async Task<AccountModel> GetAccountModel(OrgSignet orgSignet, AccountEntity Account,bool IsCreated = true)
        {
            if (string.IsNullOrEmpty(orgSignet.AccountID))
            {
                if (!IsCreated) return null; // 如果还没创建，并且不允许自动创建则返回一个空
                // 不存在创建新的
                var result = await this._eSignManager.CreateAccountAsync(Account);
            }
            else
            {
                // 存在则更新一下
                var result = await this._eSignManager.UpdateAccountAsync(Account);
            }
            // 6.获取个人账号信息
            var data = await this._eSignManager.GetAccountInfoAsync(orgSignet.RYBH);

            return data.Data;
        }

        /// <summary>
        /// 获取机构电子签章机构账号
        /// </summary>
        /// <param name="orgSignet">电子签章实体</param>
        /// <param name="Account">企业账号</param>
        /// <param name="IsCreated">不存是是否创建新的默认创建新的</param>
        /// <returns></returns>
        protected async Task<OrgAccountEntity> GetOrgAccountModel(OrgSignet orgSignet, OrgAccountEntity Account,bool IsCreated = true)
        {
            if (string.IsNullOrEmpty(orgSignet.ORGID)){
                if (!IsCreated) return null; // 如果还没创建，并且不允许自动创建则返回一个空
                var result = await this._eSignManager.CreateOrganiAccountAsync(Account);
            }
            else {
                var result = await this._eSignManager.UpdateOrganiAccountAsync(Account);
            }
            var data = await this._eSignManager.GetOrgAccountInfoAsync(this.GetOrganiSignCode(orgSignet.JGBH));

            return data.Data;
        }

        /// <summary>
        /// 修改逻辑后为了对应之前的数据不存zhxt的账户，默认添加一个新的
        /// </summary>
        protected async Task<OEconomyOrgani> CreateOrganization(string OriginalNumber)
        {
            var entity = EntityHelper.GetNewOEconomyOrgani();
            entity.Id = OriginalNumber;
            await this._oeconomyorganiManager.CreateAsync(entity);
            return entity;
        }

        /// <summary>
        ///  判断是否存在Guid
        /// </summary>
        /// <param name="attachModuleID">附件模块编号</param>
        /// <returns></returns>
        protected bool IsExistGuid(Guid attachModuleID)
        {
            return !(Guid.Empty == attachModuleID);
        }

        

        #endregion
    }
}
